package com.ocm.controller.validator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.ocm.core.constant.OCMConstant;
import com.ocm.core.dto.PropertyDefinitionDto;
import com.ocm.core.service.PropertyDefService;

@Component("propertyDefValidator")
public class PropertyDefValidator implements Validator {

   private PropertyDefService propertyDefService;

   @Autowired
   public PropertyDefValidator(@Qualifier("propertyDefService")
   PropertyDefService propertyDefService) {
      this.propertyDefService = propertyDefService;
   }

   public boolean supports(Class<?> propertyDefclass) {
      return PropertyDefinitionDto.class.isAssignableFrom(propertyDefclass);
   }

   public void validate(Object object, Errors errors) {
      validatePropertyDef(object, errors);
   }

   public void validatePropertyDef(Object object, Errors errors) {
      PropertyDefinitionDto propertyDefDto = (PropertyDefinitionDto) object;
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "err.required");
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "displayName", "err.required");
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "propertyType", "err.required");
      if (!errors.hasFieldErrors("name")) {
         if (StringUtils.containsWhitespace(propertyDefDto.getName())) {
            errors.rejectValue("name", "err.containsWhitespace");
         }
      }
   }

   public void validatePropertyDef(Long storageId, Object object, Errors errors) {
      PropertyDefinitionDto propertyDefDto = (PropertyDefinitionDto) object;
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "err.required");
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "displayName", "err.required");
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "propertyType", "err.required");
      PropertyDefinitionDto propertyDefinitionDto = (PropertyDefinitionDto) object;
      if (!errors.hasFieldErrors("name")) {
         if (StringUtils.containsWhitespace(propertyDefDto.getName())) {
            errors.rejectValue("name", "err.containsWhitespace");
         }
      }

      if (!errors.hasFieldErrors("name") && ((propertyDefinitionDto.getId() == null) || propertyDefinitionDto.getId() == 0)) {
         String propertyName = propertyDefinitionDto.getName();
         boolean existedName = propertyDefService.hasExistName(propertyName, storageId);
         if (existedName){
            errors.rejectValue("name", "err.unique");
         } else if (OCMConstant.SYSTEM_RELATED_PROPERTY.equalsIgnoreCase(propertyName) || OCMConstant.SYSTEM_SECURITY_PROPERTY.equalsIgnoreCase(propertyName)){
            errors.rejectValue("name", "err.hasSameSystem");
         }
      }
   }

   public PropertyDefService getPropertyDefService() {
      return propertyDefService;
   }

   public void setPropertyDefService(PropertyDefService propertyDefService) {
      this.propertyDefService = propertyDefService;
   }
}
